/**
 *
 *
 * *****基础实现类、可直接与socket对接的、不需要额外逻辑的*****/
export class Socket {

  //创建连接 
  $$open(ws) {
    //....具体实现代码
  }
  //关闭连接 
  $$close(callback) {
    //.... 具体实现代码
  }
  //发送订阅 
  $$0n(url, data, callback) {
    //.... 具体实现代码
  }
  //取消订阅 
  $$off(url) {
    //.... 具体实现代码
  }

  //连接成功后函数， 可在子类中实现（已实现）
  openSuccess() {}
  //连接失败后函数， 可在子类中实现（已实现）
  openFail() {}
  //消息订阅后的发布， 可在子类中实现（已实现）
  onmessage() {}

}


/**
 *
 *
 * ****个性化类*******/
export class ProxySocket extends Socket {
  constructor() {
    super();
  }

  /*
   * Status连接状态码
   * 0、未连接
   * 1、连接成功
   */
  Status = 0;
  WsUrl = "";
  /*
   * 订阅数据存储，map对象
   * kay: url
   * value: [ { url, data, callback }, ...... ]
   */
  ListenCopy = new Map();
  //订阅成功的ws Map，用于拦截客户端重复订阅
  ListenSuccessMap = {};

  getListenCopy(url) {
    return this.ListenCopy.get(url);
  }
  hasListenCopy(url) {
    return this.ListenCopy.has(url);
  }
  setListenCopy(url, data, callback) {
    const _data = [{
      url,
      data,
      callback
    }];
    if (this.hasListenCopy(url)) {
      let arr = this.getListenCopy(url);
      const hasFun = arr.filter(v => v.callback === callback).length > 0;
      arr = hasFun ? arr.map(v => {
        if (v.callback === callback) v = {
          url,
          data,
          callback
        };
        return v;
      }) : arr.concat(_data);
      this.ListenCopy.set(url, arr);
    } else {
      this.ListenCopy.set(url, _data);
    }
  }
  removeListenCopy(url, callback) {
    if (this.hasListenCopy(url)) {
      let arr = this.getListenCopy(url).filter(v => v.callback !== callback);
      this.ListenCopy.set(url, arr);
    }
  }
  clearListenCopy() {
    this.ListenCopy.clear();
  }

  setListenSuccessMap(url) {
    this.ListenSuccessMap[url] = true;
  }
  hasListenSuccessMap(url) {
    return this.ListenSuccessMap[url] === true;
  }
  removeListenSuccessMap(url) {
    delete this.ListenSuccessMap[url]
  }

  onBeforeFilter(url, data, callback) {
    if (this.hasListenSuccessMap(url)) return;
    this.setListenSuccessMap(url);
    this.$$0n(url, data, callback);
  }
  //！！！订阅入口
  on(url, data, callback) {
    this.setListenCopy(url, data, callback);
    this.Status === 1 ? this.onBeforeFilter(url, data, callback) : null;
  }
  //！！！取消订阅入口
  off(url, callback) {
    if (this.hasListenCopy(url)) {
      if (this.getListenCopy(url).length > 1) {
        this.removeListenCopy(url, callback);
      } else {
        this.$$off(url);
        this.removeListenCopy(url, callback);
        this.removeListenSuccessMap(url);
      }
    }
  }

  checkSameWs(ws) {
    if (this.WsUrl === ws) {
      throw console.error("已存在相同的socket连接.");
    }
  }
  //清除历史订阅信息，连接一个全新的ws时，优先使用
  clearResetOpen(ws) {
    this.checkSameWs(ws);
    this.clearListenCopy();
    this.resetOpen(ws);
  }
  //连接一个全新的ws时，优先使用
  resetOpen(ws) {
    this.checkSameWs(ws);
    if (this.Status === 1) {
      this.close(() => {
        this.open(ws);
      })
    } else {
      this.open(ws);
    }
  }
  //正常一般的连接ws
  open(ws) {
    this.checkSameWs(ws);
    if (this.Status === 1) return;
    this.WsUrl = ws;
    this.$$open(ws);
  }
  openSuccess() {
    this.Status = 1;
    console.warn("socket 已连接成功！");
    this.ListenCopy.forEach((v, k) => {
      v.map(v => this.onBeforeFilter(v.url, v.data, v.callback));
    })
  }
  openFail() {
    console.warn("socket 尝试重新连接");
    this.open(ws);
  }
  //关闭连接
  close(callback) {
    this.Status = 0;
    this.ListenSuccessMap = {};
    this.$$close(callback);
  }

  //！！！可根据业务数据结构修改onmessage
  onmessage({
    url,
    res
  }) {
    this.getListenCopy(url).map(v => {
      typeof v.callback === 'function' && v.callback(res);
    })
  }

}
